#include"../usr_include/MySql.h"

MySql::MySql(const char* host, const char* usrname, const char* usrpwd, const char* libname)
                : mutex_()
{
    connection = mysql_init(NULL); // 创建一个MYSQL的连接句柄

    if(!connection)
        LOG_FATAL<<"MYSQL structure false";

     // 通过用户参数信息和MYSQL句柄，连接到相应名称的数据库
    connection = mysql_real_connect(connection, host, usrname, usrpwd, libname, 0, nullptr, 0);
    
    if(!connection)
        LOG_FATAL<<"MYSQL connect false";
}

MySql::~MySql()
{
    if(connection)
        mysql_close(connection); // 关闭与MYSQL连接的句柄
}

std::vector<std::vector<netlib::string>> MySql::Query(netlib::string Rque)
{
    if(Rque.empty())
        LOG_FATAL<<"request is empty";

    //netlib::MutexLockGuard tmp(mutex_);
    std::vector<std::vector<netlib::string>> collect; // 创建保存结果的容器

    if(mysql_query(connection, Rque.c_str()) != 0) // 传入SQL语句，进行数据库操作
	{
		// LOG_FATAL<<"Query false";
		return collect;
	}


    // 传入SQL语句后，从连接句柄中读取结果集，result是一个在堆区的缓冲区，需要手动释放
    result = mysql_use_result(connection);

    // mysql_field_count(connection) 查看上次执行语句的结果集的列数
    // mysql_num_fields(result) 查看结果集有多少行
    // mysql_num_fields(result) 查看每一行有多少列(字段)
    for(int i=0; i < mysql_num_fields(result); ++i)
    {
        std::vector<netlib::string> sl;
        row = mysql_fetch_row(result); // mysql_fetch_row 获取结果集的下一行
        if(row == nullptr)
            break;
        for(int j=0; j < mysql_num_fields(result); ++j)
            sl.push_back(row[j]);
        if(!sl.empty())
            collect.push_back(sl);
    }

    mysql_free_result(result); // 释放结果集的缓冲区

    return collect;
}

bool MySql::Modify(netlib::string Rque) // 执行非查询语句，如增、删、改语句
{
    if(Rque.empty())
        LOG_FATAL<<"request is empty";
    
    netlib::MutexLockGuard tmp(mutex_);

    if(mysql_query(connection, Rque.c_str()) != 0) // 传入SQL语句，进行数据库操作
		LOG_FATAL<< Rque.c_str();
        // LOG_FATAL<<"Query false";

     // 非查询语句执行成功时，结果集为空指针，mysql_field_count返回0
    result = mysql_use_result(connection);

    // mysql_affected_rows 返回update,insert,delete影响的行数
    if(result==nullptr && mysql_field_count(connection) == 0)
    {
        LOG_INFO<<"Modify impact "<<mysql_affected_rows(connection)<<" line";
        return true;
    }
    
    LOG_FATAL<<"Get result error "<< mysql_error(connection);
    return false;
}
